'''
Created on 2013-01-21

@author: levi
'''

import pydot

from copy import deepcopy
    

def graph_to_dot(name, g, verbosity = 0):
    """
    build a dot file from a himesis graph
    verbosity = 0, no traceability in the dot graph
    verbosity = 1, traceability in the dot graph
    """
    vattr=''
    nodes = {}
    graph = pydot.Dot(name, graph_type='digraph')
    for v in g.vs:
        if str(v['mm__']) == 'MatchModel' or str(v['mm__']) == 'match_contains' or\
           str(v['mm__']) == 'ApplyModel' or str(v['mm__']) == 'apply_contains' or str(v['mm__']) == 'paired_with':
            vattr += str(v['mm__']) 
            vattr += ' < '     
#            vattr += str(v['associationType'])                                                                                                                                                                                     
            vattr += ' < '
            vattr += str(v['GUID__'])[-12:]     
            nodes[v.index] = pydot.Node(vattr, style="filled", fillcolor="lightgray")
            graph.add_node(nodes[v.index])  
        elif str(v['mm__']) == 'directLink_S' or str(v['mm__']) == 'directLink_T':
            vattr += str(v['mm__']) 
            vattr += ' < '     
#            vattr += str(v['associationType'])                                                                                                                                                                                     
            vattr += ' < '
            vattr += str(v['GUID__'])[-12:]                 
            nodes[v.index] = pydot.Node(vattr, style="filled", fillcolor="lightyellow")
            graph.add_node(nodes[v.index])              
        elif str(v['mm__']) == 'indirectLink_S' or str(v['mm__']) == 'indirectLink_T':
            vattr += str(v['mm__']) 
            vattr += ' < '     
            vattr += str(v['GUID__'])[-12:]                 
            nodes[v.index] = pydot.Node(vattr, style="filled", fillcolor="lightgreen") 
            graph.add_node(nodes[v.index])               
        elif str(v['mm__']) == 'backward_link':
            vattr += str(v['mm__']) 
            vattr += ' < '
            vattr += str(v['GUID__'])[-12:]
            nodes[v.index] = pydot.Node(vattr, style="filled", fillcolor="coral")
            graph.add_node(nodes[v.index])  
        elif str(v['mm__']) == 'trace_link':
            if  verbosity == 1:
                vattr += str(v['mm__']) 
                vattr += ' < '
                vattr += str(v['GUID__'])[-12:]
                nodes[v.index] = pydot.Node(vattr, style="filled", fillcolor="chocolate")   
        else:
            vattr += str(v['mm__']) 
            vattr += ' < '     
            vattr += str(v['cardinality']) 
            vattr += ' < '     
            vattr += str(v['GUID__'])[-12:]
            nodes[v.index] = pydot.Node(vattr, style="filled", fillcolor="lightblue")
            graph.add_node(nodes[v.index])  
        vattr = ''
    for e in g.es:
        if verbosity == 0:
            if g.vs[e.source]['mm__'] != 'trace_link' and g.vs[e.target]['mm__'] != 'trace_link':
                graph.add_edge(pydot.Edge(nodes[e.source],nodes[e.target]))
        else:
            graph.add_edge(pydot.Edge(nodes[e.source],nodes[e.target]))

                           
    graph.write('/home/levi/Desktop/%s.dot'%name)     
#    graph.write('/home/gehan/OutputDotFiles/%s.dot'%name)    

    
def disjoint_model_union(first, second):
    """
    merge two himesis graphs
    IMPORTANT: only makes sense if the graphs are instances of the same metamodel
    """
    
    nr_attr_first = len(first.vs[0].attribute_names())
    nr_attr_second = len(second.vs[0].attribute_names())
    
    # graphs need to be swapped in case the nodes in the second graph have more attributes than the ones in the first
    # this is so because each node in a model has the maximum amount of attributes used in the model
    
    if nr_attr_second > nr_attr_first:
        swapbuffer = deepcopy(second)
        second = deepcopy(first)
        first = swapbuffer

    # get the list of attributes to copy from the second graph but don't copy the GUIDs because they are newly created        
    attribute_names = [attr for attr in second.vs[0].attribute_names() if attr != 'GUID__']
    nb_nodes_first = len(first.vs)
    
    # first copy the nodes
    for index_v in range(len(second.vs)):
        first.add_node()
        for attr_name in attribute_names:
            first.vs[nb_nodes_first + index_v][attr_name] = second.vs[index_v][attr_name]

    # then copy the edges
    for index_e in range(len(second.es)):
        first.add_edges((nb_nodes_first + second.es[index_e].tuple[0],nb_nodes_first + second.es[index_e].tuple[1]))
        
    first.name = first.name + '-' + second.name
 
    return first


def print_graph(graph):
    """
    merge two himesis graphs
    IMPORTANT: only makes sense if the graphs are instances of the same metamodel
    """
    # first print the nodes
    print 'Name: ' + graph.name
    
    print 'Nodes: '
    for v in graph.vs:
        print v
    
    # then print the edges
    print 'Edges: '
    for e in graph.es:
        print e  